#pragma once 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include <cstring>

class InetAddr 
{
    private:
        sockaddr_in _net_addr;
        uint16_t _port;
        socklen_t _len;
        std::string _ip;
        void NetPort2Host()
            {
                _port = ::ntohs(_net_addr.sin_port);
            }
        void NetIp2Host()
        {
            char Ip[64];
            ::inet_ntop(AF_INET,&(_net_addr.sin_addr),Ip,sizeof(Ip));
            _ip = Ip;
        }
    public:
        InetAddr (){}

        InetAddr& operator=(const InetAddr& client){
            _net_addr = client.raddr();
            _len = sizeof(_net_addr);
            _ip = client._ip;
            _port = client._port;
            return *this;
        }

        InetAddr (sockaddr_in& peer) :_net_addr(peer)
        {
            NetPort2Host();
            NetIp2Host();
            _len = sizeof(_net_addr);
        }

        std::string Ip() {return _ip;}
        std::string Info() {return _ip + ":" + std::to_string(_port);}
        sockaddr* NetAddr() {return (sockaddr*)(&_net_addr);}
        InetAddr (uint16_t port) :_port(port)
            {
                memset(&_net_addr,0,sizeof(_net_addr));
                _net_addr.sin_family = AF_INET;
                _net_addr.sin_port = ::htons(_port);
                _net_addr.sin_addr.s_addr = INADDR_ANY;
                _len = sizeof(_net_addr);
            }
        uint16_t Port() {return _port;}
        sockaddr_in   raddr() const {return _net_addr;}         
        sockaddr_in* addr() {return &_net_addr;}
        socklen_t Len () { return _len;}
        ~InetAddr (){}

};